package mbean;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.faces.model.SelectItem;

import org.richfaces.component.state.TreeState;

import util.Constantes;
import util.FacesUtil;
import vo.BSCPerspectiveVO;
import vo.BscGoalVO;
import vo.BscVO;
import vo.MetricVO;
import vo.SwotElementVO;
import vo.SwotVO;
import vo.TreeNodeVO;
import dao.BscDAO;
import dao.SwotDAO;

public class BSCMbean extends AbstractMBean{

	private int strategicPlanId, idGoal;
	private BscDAO dao;	
	private BscVO bscVO;
	private String nameGoal, swotElementSelected, perspectiveName, swotElementName, swotElementRelevance, swotElementType, perspectiveGoal, 
				   perspectiveGoalOld, perspectiveSwot;
	private Map<String, BSCPerspectiveVO> mapaBsc;
	private List<SelectItem> listPerspectives;
	private Map<String, List<String>> mapaSwotElementPerspective;
	private Map<String, SwotElementVO> mapaSWOT;	
	private List<TreeNodeVO> treeBSCPerspective;
	private List<String> listSwotElement, listaSwotElementDerived;
	private TreeState treeState;
	
	public BSCMbean(){
		this.dao = new BscDAO();		
	}
	
	public String open(){
		this.strategicPlanId = ((StrategyMBean) FacesUtil.getSessionMapValue("strategy")).getStrategicPlanId();
		this.bscVO = dao.getBsc(this.strategicPlanId);		
		this.mapaBsc = this.bscVO.getMapaBscPerspective();
		
		loadTree();
		preparaTelaNewGoal();
		setaTela(false, "");
		
		return "bsc";
	}
	
	private TreeNodeVO createNode(int id, String name, String code){
		TreeNodeVO vo = new TreeNodeVO();
		vo.setId(id);
		vo.setName(name);
		vo.setCode(code);
		vo.setChild(new ArrayList<TreeNodeVO>());
		return vo;
	}

	private void loadTree(){		
		this.treeBSCPerspective = new ArrayList<TreeNodeVO>();
		
		TreeNodeVO noRaiz = createNode(0, this.bscVO.getOrganizationName() + " - " + this.bscVO.getStrategicPlanName(), "");
		
		for(String key:this.mapaBsc.keySet()){
			BSCPerspectiveVO bscvo = this.mapaBsc.get(key);
			TreeNodeVO nodePerspective = createNode(bscvo.getId(), bscvo.getPerspective(), bscvo.getAcronym());
			
			for(BscGoalVO vo: this.mapaBsc.get(key).getListaBscGoal()){
				TreeNodeVO nodeObjetivo = createNode(vo.getId(), vo.getName(), "");
				
				TreeNodeVO nodeSWOT = createNode(0, FacesUtil.getMessageResourceString("relatedSwotElementTree"), "");
				for(SwotElementVO sevo:vo.getListDerivedSwotElement()){
					TreeNodeVO nodeSwotElement = createNode(sevo.getId(), sevo.getElementType() + " - " + sevo.getName(), "");
					nodeSWOT.getChild().add(nodeSwotElement);
				}
				
				nodeObjetivo.getChild().add(nodeSWOT);
				nodePerspective.getChild().add(nodeObjetivo);
			}
			
			noRaiz.getChild().add(nodePerspective);
		}
		
		this.treeBSCPerspective.add(noRaiz);
	}

	public void setStrategicPlanId(int strategicPlanId) {
		this.strategicPlanId = strategicPlanId;
	}

	public int getStrategicPlanId() {
		return strategicPlanId;
	}

	public BscVO getBscVO() {
		return bscVO;
	}

	public void setBscVO(BscVO bscVO) {
		this.bscVO = bscVO;
	}
	
	public void save(){
		this.dao.save(this.bscVO);			
		MenuMBean mmb = (MenuMBean) FacesUtil.getSessionMapValue("menu");
		mmb.loadTree();		
	}

	public void preparaTelaNewGoal(){
		this.listaSwotElementDerived = new ArrayList<String>();		
		this.mapaSwotElementPerspective = new HashMap<String, List<String>>();
		this.mapaSWOT = new HashMap<String, SwotElementVO>();
		this.listPerspectives = new ArrayList<SelectItem>();
		this.perspectiveGoal = "";
		this.nameGoal = "";
		this.idGoal = 0;
		
		preparaTela();
	}
	
	private void preparaTela(){
		for(String key:this.mapaBsc.keySet()){
			SelectItem si = new SelectItem();
			si.setLabel(this.mapaBsc.get(key).getPerspective());
			si.setValue(this.mapaBsc.get(key).getAcronym());
			si.setEscape(false);
			si.setDescription(this.mapaBsc.get(key).getPerspective());
			
			this.listPerspectives.add(si);			
		}
		
		SwotDAO swotDAO = new SwotDAO();
		SwotVO swotVO = swotDAO.getSwot(this.strategicPlanId);
		
		populaMapaSwot(swotVO.getListStrength());
		populaMapaSwot(swotVO.getListWeakness());
		populaMapaSwot(swotVO.getListOpportunity());
		populaMapaSwot(swotVO.getListThreat());
		
		this.listSwotElement = this.mapaSwotElementPerspective.get(this.listPerspectives.get(0).getValue());
	}

	private void populaMapaSwot(List<SwotElementVO> listSwotElement) {
		for(SwotElementVO svo:listSwotElement){
			for(String key: svo.getListPerspectives()){
				if (! this.mapaSwotElementPerspective.containsKey(key)){
					this.mapaSwotElementPerspective.put(key, new ArrayList<String>());
				}

				this.mapaSwotElementPerspective.get(key).add(Integer.toString(svo.getId()));				
			}
			
			this.mapaSWOT.put(Integer.toString(svo.getId()), svo);
		}
	}

	public void setPerspectiveGoal(String perspectiveGoal) {
		this.perspectiveGoal = perspectiveGoal;
	}

	public String getPerspectiveGoal() {
		return perspectiveGoal;
	}

	public List<SelectItem> getListPerspectives() {
		return listPerspectives;
	}

	public void setListPerspectives(List<SelectItem> listPerspectives) {
		this.listPerspectives = listPerspectives;
	}

	public void setNameGoal(String nameGoal) {
		this.nameGoal = nameGoal;
	}

	public String getNameGoal() {
		return nameGoal;
	}
	
	public String saveGoal(){		
		BscGoalVO goalVO;
		
		if (validaGoal()){
			if (this.idGoal == 0){
				goalVO = new BscGoalVO();
				goalVO.setStatus(Constantes.INSERT);
			}
			else{
				goalVO = this.mapaBsc.get(this.perspectiveGoal).getMapaBscGoal().get(this.idGoal);
				goalVO.setStatus(Constantes.UPDATE);
			}		
			
			goalVO.setName(this.nameGoal);
			goalVO.setPerspectivaId(this.mapaBsc.get(this.perspectiveGoal).getId());
			goalVO.setListDerivedSwotElement(new ArrayList<SwotElementVO>());
			goalVO.setMetrics(new ArrayList<MetricVO>());
			
			for(String key:listaSwotElementDerived){
				goalVO.getListDerivedSwotElement().add(this.mapaSWOT.get(key));
			}
			
			if (this.idGoal == 0){
				this.mapaBsc.get(this.perspectiveGoal).getListaBscGoal().add(goalVO);
			}
			else{
				if (! this.perspectiveGoalOld.equalsIgnoreCase(this.perspectiveGoal)){
					this.mapaBsc.get(this.perspectiveGoalOld).removeBscGoal(this.idGoal);
					this.mapaBsc.get(this.perspectiveGoal).getListaBscGoal().add(goalVO);
				}
			}
			
			loadTree();	
			save();
		}
		
		return "#";
	}

	private boolean validaGoal() {
		boolean retorno = true;
		
		if (this.perspectiveGoal.equalsIgnoreCase("")){
			retorno = false;
			FacesUtil.addErrorMessage(FacesUtil.getMessageResourceString("errorPerspectiveRequired"));
		}
		
		if (this.nameGoal.equalsIgnoreCase("")){
			retorno = false;
			FacesUtil.addErrorMessage(FacesUtil.getMessageResourceString("errorNameRequired"));
		}
		
		return retorno;
	}

	public void setListaSwotElementDerived(List<String> listaSwotElementDerived) {
		this.listaSwotElementDerived = listaSwotElementDerived;
	}

	public List<String> getListaSwotElementDerived() {
		return listaSwotElementDerived;
	}

	public void setListSwotElement(List<String> listSwotElement) {
		this.listSwotElement = listSwotElement;
	}

	public List<String> getListSwotElement() {
		return listSwotElement;
	}
	
	public void filterPerspective(){
		if (this.mapaSwotElementPerspective.containsKey(this.perspectiveSwot)){
			this.listSwotElement = this.mapaSwotElementPerspective.get(this.perspectiveSwot);
			this.listSwotElement.removeAll(this.listaSwotElementDerived);
		}
		else{
			this.listSwotElement = new ArrayList<String>();
		}
	}

	public void setTreeBSCPerspective(List<TreeNodeVO> treeBSCPerspective) {
		this.treeBSCPerspective = treeBSCPerspective;
	}

	public List<TreeNodeVO> getTreeBSCPerspective() {
		return treeBSCPerspective;
	}
	
	public void viewGoal(){
		preparaTela();
		
		BscGoalVO vo = this.mapaBsc.get(this.perspectiveGoalOld).getMapaBscGoal().get(this.idGoal);
		
		this.nameGoal = vo.getName();
		this.perspectiveGoal = this.perspectiveGoalOld;
		
		for(SwotElementVO swot:vo.getListDerivedSwotElement()){
			this.listaSwotElementDerived.add(Integer.toString(swot.getId()));
		}
		
		this.listSwotElement = this.mapaSwotElementPerspective.get(this.perspectiveGoal);
		this.listSwotElement.removeAll(this.listaSwotElementDerived);		
	}

	public void setIdGoal(int idGoal) {
		this.idGoal = idGoal;
	}

	public int getIdGoal() {
		return idGoal;
	}

	public Map<String, SwotElementVO> getMapaSWOT() {
		return mapaSWOT;
	}

	public void setMapaSWOT(Map<String, SwotElementVO> mapaSWOT) {
		this.mapaSWOT = mapaSWOT;
	}

	public void setSwotElementSelected(String swotElementSelected) {
		this.swotElementSelected = swotElementSelected;
	}

	public String getSwotElementSelected() {
		return swotElementSelected;
	}

	public void setPerspectiveName(String perspectiveName) {
		this.perspectiveName = perspectiveName;
	}

	public String getPerspectiveName() {
		return perspectiveName;
	}

	public void setSwotElementName(String swotElementName) {
		this.swotElementName = swotElementName;
	}

	public String getSwotElementName() {
		return swotElementName;
	}

	public void setSwotElementRelevance(String swotElementRelevance) {
		this.swotElementRelevance = swotElementRelevance;
	}

	public String getSwotElementRelevance() {
		return swotElementRelevance;
	}
	
	public void viewSwotElement(){
		SwotElementVO vo = this.mapaSWOT.get(this.swotElementSelected);
		
		this.swotElementName = vo.getName();
		this.swotElementRelevance = vo.getRelevancia();
		this.swotElementType = vo.getElementTypeExtenso();
		this.perspectiveName = vo.getPerspective();
	}

	public void setSwotElementType(String swotElementType) {
		this.swotElementType = swotElementType;
	}

	public String getSwotElementType() {
		return swotElementType;
	}

	public void setTreeState(TreeState treeState) {
		this.treeState = treeState;
	}

	public TreeState getTreeState() {
		return treeState;
	}

	public String getPerspectiveSwot() {
		return perspectiveSwot;
	}

	public void setPerspectiveSwot(String perspectiveSwot) {
		this.perspectiveSwot = perspectiveSwot;
	}

	public String getPerspectiveGoalOld() {
		return perspectiveGoalOld;
	}

	public void setPerspectiveGoalOld(String perspectiveGoalOld) {
		this.perspectiveGoalOld = perspectiveGoalOld;
	}

	@Override
	public boolean isDirty() {
		// TODO Auto-generated method stub
		return false;
	}
}